Skip to content

Commit 122451d

Browse files
authored
Merge pull request #28847 from apple/tensorflow-merge
Merge tag 'swift-DEVELOPMENT-SNAPSHOT-2019-12-16-a ' into tensorflow
2 parents d8df472 + 4e1bef0 commit 122451d

File tree

316 files changed

+17768
-9476
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

316 files changed

+17768
-9476
lines changed

CHANGELOG.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,21 @@ CHANGELOG
2626
Swift 5.2
2727
---------
2828

29+
* [SR-11841][]:
30+
31+
When chaining calls to `filter(_:)` on a lazy sequence or collection, the
32+
filtering predicates will now be called in the same order as eager filters.
33+
34+
```swift
35+
let evens = (1...10).lazy
36+
.filter { $0.isMultiple(of: 2) }
37+
.filter { print($0); return true }
38+
_ = evens.count
39+
// Prints 2, 4, 6, 8, and 10 on separate lines
40+
```
41+
42+
Previously, the predicates were called in reverse order.
43+
2944
* [SR-2790][]:
3045

3146
The compiler will now emit a warning when attempting to pass a temporary
@@ -7874,3 +7889,4 @@ Swift 1.0
78747889
[SR-9827]: <https://bugs.swift.org/browse/SR-9827>
78757890
[SR-11298]: <https://bugs.swift.org/browse/SR-11298>
78767891
[SR-11429]: <https://bugs.swift.org/browse/SR-11429>
7892+
[SR-11841]: <https://bugs.swift.org/browse/SR-11841>

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ Please make sure you use Python 2.x. Python 3.x is not supported currently.
3333

3434
#### macOS
3535

36-
To build for macOS, you need [Xcode 11.2](https://developer.apple.com/xcode/downloads/).
36+
To build for macOS, you need [Xcode 11.3](https://developer.apple.com/xcode/downloads/).
3737
The required version of Xcode changes frequently, and is often a beta release.
3838
Check this document for the current required version.
3939

benchmark/single-source/ArrayOfGenericRef.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class ConstructibleArray<T:Constructible> {
3434
array = [T]()
3535
array.reserveCapacity(1_000)
3636
for _ in 0...1_000 {
37-
array.append(T(e:e) as T)
37+
array.append(T(e:e))
3838
}
3939
}
4040
}

benchmark/single-source/ArrayOfRef.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class ConstructibleArray<T:Constructible> {
3535
array = [T]()
3636
array.reserveCapacity(1_000)
3737
for _ in 0...1_000 {
38-
array.append(T(e:e) as T)
38+
array.append(T(e:e))
3939
}
4040
}
4141
}

benchmark/single-source/StringWalk.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ import TestsUtils
6666
let ascii =
6767
"siebenhundertsiebenundsiebzigtausendsiebenhundertsiebenundsiebzig"
6868
let emoji = "👍👩‍👩‍👧‍👧👨‍👨‍👦‍👦🇺🇸🇨🇦🇲🇽👍🏻👍🏼👍🏽👍🏾👍🏿"
69-
let utf16 = emoji + "the quick brown fox" + String(emoji.reversed() as Array<Character>)
69+
let utf16 = emoji + "the quick brown fox" + String(emoji.reversed())
7070

7171
let japanese = "今回のアップデートでSwiftに大幅な改良が施され、安定していてしかも直感的に使うことができるAppleプラットフォーム向けプログラミング言語になりました。"
7272
let chinese = "Swift 是面向 Apple 平台的编程语言,功能强大且直观易用,而本次更新对其进行了全面优化。"

benchmark/single-source/StringWalk.swift.gyb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ import TestsUtils
6767
let ascii =
6868
"siebenhundertsiebenundsiebzigtausendsiebenhundertsiebenundsiebzig"
6969
let emoji = "👍👩‍👩‍👧‍👧👨‍👨‍👦‍👦🇺🇸🇨🇦🇲🇽👍🏻👍🏼👍🏽👍🏾👍🏿"
70-
let utf16 = emoji + "the quick brown fox" + String(emoji.reversed() as Array<Character>)
70+
let utf16 = emoji + "the quick brown fox" + String(emoji.reversed())
7171

7272
let japanese = "今回のアップデートでSwiftに大幅な改良が施され、安定していてしかも直感的に使うことができるAppleプラットフォーム向けプログラミング言語になりました。"
7373
let chinese = "Swift 是面向 Apple 平台的编程语言,功能强大且直观易用,而本次更新对其进行了全面优化。"

benchmark/utils/DriverUtils.swift

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -412,9 +412,10 @@ final class TestRunner {
412412
private static func getExecutedInstructions() -> UInt64 {
413413
if #available(OSX 10.9, iOS 7.0, *) {
414414
var u = rusage_info_v4()
415-
let p = UnsafeMutablePointer(&u)
416-
p.withMemoryRebound(to: Optional<rusage_info_t>.self, capacity: 1) { up in
417-
let _ = proc_pid_rusage(getpid(), RUSAGE_INFO_V4, up)
415+
withUnsafeMutablePointer(to: &u) { p in
416+
p.withMemoryRebound(to: Optional<rusage_info_t>.self, capacity: 1) { up in
417+
let _ = proc_pid_rusage(getpid(), RUSAGE_INFO_V4, up)
418+
}
418419
}
419420
return u.ri_instructions
420421
} else {

docs/CompilerPerformance.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -793,7 +793,7 @@ performance between two compilers, say `${OLD}/swiftc` and `${NEW}/swiftc`:
793793
```
794794
$ mkdir stats-old stats-new
795795
$ ${OLD}/swiftc -stats-output-dir stats-old test.swift
796-
$ ${OLD}/swiftc -stats-output-dir stats-new test.swift
796+
$ ${NEW}/swiftc -stats-output-dir stats-new test.swift
797797
$ utils/process-stats-dir.py --compare-stats-dirs stats-old stats-new
798798
old new delta_pct name
799799
1402939 1430732 1.98 AST.NumASTBytesAllocated

docs/DifferentiableProgramming.md

Lines changed: 126 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ Backticks were added manually.
7272
* [Upcasting to non-`@differentiable` functions](#upcasting-to-non-differentiable-functions)
7373
* [Implied generic constraints](#implied-generic-constraints)
7474
* [Non-differentiable parameters](#non-differentiable-parameters)
75+
* [Higher-order functions and currying](#higher-order-functions-and-currying)
7576
* [Differential operators](#differential-operators)
7677
* [Differential-producing differential operators](#differential-producing-differential-operators)
7778
* [Pullback-producing differential operators](#pullback-producing-differential-operators)
@@ -88,7 +89,6 @@ Backticks were added manually.
8889
* [Convolutional neural networks (CNN)](#convolutional-neural-networks-cnn)
8990
* [Recurrent neural networks (RNN)](#recurrent-neural-networks-rnn)
9091
* [Future directions](#future-directions)
91-
* [Differentiation of higher-order functions](#differentiation-of-higher-order-functions)
9292
* [Higher-order differentiation](#higher-order-differentiation)
9393
* [Naming conventions for numerical computing](#naming-conventions-for-numerical-computing)
9494
* [Source compatibility](#source-compatibility)
@@ -1452,8 +1452,11 @@ making the other function linear.
14521452

14531453
A protocol requirement or class method/property/subscript can be made
14541454
differentiable via a derivative function or transpose function defined in an
1455-
extension. A dispatched call to such a member can be differentiated even if the
1456-
concrete implementation is not differentiable.
1455+
extension. When a protocol requirement is not marked with `@differentiable` but
1456+
has been made differentiable by a `@derivative` or `@transpose` declaration in a
1457+
protocol extension, a dispatched call to such a member can be differentiated,
1458+
and the derivative or transpose is always the one provided in the protocol
1459+
extension.
14571460

14581461
#### Linear maps
14591462

@@ -1696,48 +1699,49 @@ public protocol ElementaryFunctions {
16961699
...
16971700
}
16981701

1699-
public extension ElementaryFunctions where Self: Differentiable, Self == Self.TangentVector {
1702+
public extension ElementaryFunctions
1703+
where Self: Differentiable & FloatingPoint, Self == Self.TangentVector {
17001704
@inlinable
17011705
@derivative(of: sqrt)
1702-
func _(_ x: Self) -> (value: Self, differential: @differential(linear) (Self) -> Self) {
1706+
static func _(_ x: Self) -> (value: Self, differential: @differentiable(linear) (Self) -> Self) {
17031707
(sqrt(x), { dx in (1 / 2) * (1 / sqrt(x)) * dx })
17041708
}
17051709

17061710
@inlinable
17071711
@derivative(of: cos)
1708-
func _(_ x: Self) -> (value: Self, differential: @differential(linear) (Self) -> Self) {
1712+
static func _(_ x: Self) -> (value: Self, differential: @differentiable(linear) (Self) -> Self) {
17091713
(cos(x), { dx in -sin(x) * dx })
17101714
}
17111715

17121716
@inlinable
17131717
@derivative(of: asinh)
1714-
func _(_ x: Self) -> (value: Self, differential: @differential(linear) (Self) -> Self) {
1718+
static func _(_ x: Self) -> (value: Self, differential: @differentiable(linear) (Self) -> Self) {
17151719
(asinh(x), { dx in 1 / (1 + x * x) * dx })
17161720
}
17171721

17181722
@inlinable
17191723
@derivative(of: exp)
1720-
func _(_ x: Self) -> (value: Self, differential: @differential(linear) (Self) -> Self) {
1724+
static func _(_ x: Self) -> (value: Self, differential: @differentiable(linear) (Self) -> Self) {
17211725
let ret = exp(x)
17221726
return (ret, { dx in ret * dx })
17231727
}
17241728

17251729
@inlinable
17261730
@derivative(of: exp10)
1727-
func _(_ x: Self) -> (value: Self, differential: @differential(linear) (Self) -> Self) {
1731+
static func _(_ x: Self) -> (value: Self, differential: @differentiable(linear) (Self) -> Self) {
17281732
let ret = exp10(x)
17291733
return (ret, { dx in exp(10) * ret * dx })
17301734
}
17311735

17321736
@inlinable
17331737
@derivative(of: log)
1734-
func _(_ x: Self) -> (value: Self, differential: @differential(linear) (Self) -> Self) { dx in
1735-
(log(x), { 1 / x * dx })
1738+
static func _(_ x: Self) -> (value: Self, differential: @differentiable(linear) (Self) -> Self) {
1739+
(log(x), { dx in 1 / x * dx })
17361740
}
17371741

17381742
@inlinable
17391743
@derivative(of: pow)
1740-
func _(_ x: Self, _ y: Self) -> (value: Self, differential: @differential(linear) (Self, Self) -> Self) {
1744+
static func _(_ x: Self, _ y: Self) -> (value: Self, differential: @differentiable(linear) (Self, Self) -> Self) {
17411745
(pow(x, y), { (dx, dy) in
17421746
let l = y * pow(x, y-1) * dx
17431747
let r = pow(x, y) * log(x) * dy
@@ -1749,6 +1753,73 @@ public extension ElementaryFunctions where Self: Differentiable, Self == Self.Ta
17491753
}
17501754
```
17511755

1756+
#### Default derivatives
1757+
1758+
In a protocol extension, class definition, or class extension, providing a
1759+
derivative or transpose for a protocol extension or a non-final class member is
1760+
considered as providing a default derivative for that member. Types that conform
1761+
to the protocol or inherit from the class can inherit the default derivative.
1762+
1763+
If the original member does not have a `@differentiable` attribute, a default
1764+
derivative is implicitly added to all conforming/overriding implementations.
1765+
1766+
```swift
1767+
protocol P {
1768+
func foo(_ x: Float) -> Float
1769+
}
1770+
1771+
extension P {
1772+
@derivative(of: foo(x:))
1773+
func _(_ x: Float) -> (value: Float, differential: (Float) -> Float) {
1774+
(value: foo(x), differential: { _ in 42 })
1775+
}
1776+
}
1777+
1778+
struct S: P {
1779+
func foo(_ x: Float) -> Float {
1780+
33
1781+
}
1782+
}
1783+
1784+
let s = S()
1785+
let d = derivative(at: 0) { x in
1786+
s.foo(x)
1787+
} // ==> 42
1788+
```
1789+
1790+
When a protocol requirement or class member is marked with `@differentiable`, it
1791+
is considered as a _differentiability customization point_. This means that all
1792+
conforming/overriding implementation must provide a corresponding
1793+
`@differentiable` attribute, which causes the implementation to be
1794+
differentiated. To inherit the default derivative without differentiating the
1795+
implementation, add `default` to the `@differentiable` attribute.
1796+
1797+
```swift
1798+
protocol P {
1799+
@differentiable
1800+
func foo(_ x: Float) -> Float
1801+
}
1802+
1803+
extension P {
1804+
@derivative(of: foo(x:))
1805+
func _(_ x: Float) -> (value: Float, differential: (Float) -> Float) {
1806+
(value: foo(x), differential: { _ in 42 })
1807+
}
1808+
}
1809+
1810+
struct S: P {
1811+
@differentiable(default) // Inherits default derivative for `P.foo(_:)`.
1812+
func foo(_ x: Float) -> Float {
1813+
33
1814+
}
1815+
}
1816+
1817+
let s = S()
1818+
let d = derivative(at: 0) { x in
1819+
s.foo(x)
1820+
} // ==> 42
1821+
```
1822+
17521823
### Differentiable function types
17531824

17541825
Differentiability is a fundamental mathematical concept that applies not only to
@@ -2002,6 +2073,43 @@ _ = f0 as @differentiable (@noDerivative Float, Float) -> Float
20022073
_ = f0 as @differentiable (@noDerivative Float, @noDerivative Float) -> Float
20032074
```
20042075

2076+
#### Higher-order functions and currying
2077+
2078+
As defined above, the `@differentiable` function type attributes requires all
2079+
non-`@noDerivative` arguments and results to conform to the `@differentiable`
2080+
attribute. However, there is one exception: when the type of an argument or
2081+
result is a function type, e.g. `@differentiable (T) -> @differentiable (U) ->
2082+
V`. This is because we need to differentiate higher-order funtions.
2083+
2084+
Mathematically, the differentiability of `@differentiable (T, U) -> V` is
2085+
similar to that of `@differentiable (T) -> @differentiable (U) -> V` in that
2086+
differentiating either one will provide derivatives with respect to parameters
2087+
`T` and `U`. Here are some examples of first-order function types and their
2088+
corresponding curried function types:
2089+
2090+
| First-order function type | Curried function type |
2091+
|---------------------------------------------|---------------------------------------------------|
2092+
| `@differentiable (T, U) -> V` | `@differentiable (T) -> @differentiable (U) -> V` |
2093+
| `@differentiable (T, @noDerivative U) -> V` | `@differentiable (T) -> (U) -> V` |
2094+
| `@differentiable (@noDerivative T, U) -> V` | `(T) -> @differentiable (U) -> V` |
2095+
2096+
A curried differentiable function can be formed like any curried
2097+
non-differentiable function in Swift.
2098+
2099+
```swift
2100+
func curry<T, U, V>(
2101+
_ f: @differentiable (T, U) -> V
2102+
) -> @differentiable (T) -> @differentiable (U) -> V {
2103+
{ x in { y in f(x, y) } }
2104+
}
2105+
```
2106+
2107+
The way this works is that the compiler internally assigns a tangent bundle to a
2108+
closure that captures variables. This tangent bundle is existentially typed,
2109+
because closure contexts are type-erased in Swift. The theory behind the typing
2110+
rules has been published as [The Differentiable
2111+
Curry](https://www.semanticscholar.org/paper/The-Differentiable-Curry-Plotkin-Brain/187078bfb159c78cc8c78c3bbe81a9176b3a6e02).
2112+
20052113
### Differential operators
20062114

20072115
The core differentiation APIs are the differential operators. Differential
@@ -2021,7 +2129,7 @@ func valueWithDifferential<T, R>(
20212129
) -> (value: R,
20222130
differential: @differentiable(linear) (T.TangentVector) -> R.TangentVector) {
20232131
// Compiler built-in.
2024-
Builtin.autodiffApply_jvp_arity1(body, x)
2132+
Builtin.applyDerivative_arity1(body, x)
20252133
}
20262134

20272135

@@ -2030,7 +2138,7 @@ func transpose<T, R>(
20302138
of body: @escaping @differentiable(linear) (T) -> R
20312139
) -> @differentiable(linear) (R) -> T {
20322140
// Compiler built-in.
2033-
{ x in Builtin.autodiffApply_transpose(body, x) }
2141+
{ x in Builtin.applyTranspose_arity1(body, x) }
20342142
}
20352143
```
20362144

@@ -2203,13 +2311,13 @@ whether the derivative is always zero and warns the user.
22032311

22042312
```swift
22052313
let grad = gradient(at: 1.0) { x in
2206-
3.squareRoot()
2314+
Double(3).squareRoot()
22072315
}
22082316
```
22092317

22102318
```console
2211-
test.swift:4:18: warning: result does not depend on differentiation arguments and will always have a zero derivative; do you want to add '.withoutDerivative()' to make it explicit?
2212-
3.squareRoot()
2319+
test.swift:4:18: warning: result does not depend on differentiation arguments and will always have a zero derivative; do you want to use 'withoutDerivative(at:)' to make it explicit?
2320+
Double(3).squareRoot()
22132321
^
22142322
withoutDerivative(at:)
22152323
```
@@ -2456,30 +2564,6 @@ typealias LSTM<Scalar: TensorFlowFloatingPoint> = RNN<LSTMCell<Scalar>>
24562564

24572565
## Future directions
24582566

2459-
### Differentiation of higher-order functions
2460-
2461-
Mathematically, the differentiability of `@differentiable (T, U) -> V` is
2462-
similar to that of `@differentiable (T) -> @differentiable (U) -> V` in that
2463-
differentiating either one will provide derivatives with respect to parameters
2464-
`T` and `U`.
2465-
2466-
To form a `@differentiable (T) -> @differentiable (U) -> V`, the most natural
2467-
thing to do is currying, which one might implement as:
2468-
2469-
```swift
2470-
func curry<T, U, V>(
2471-
_ f: @differentiable (T, U) -> V
2472-
) -> @differentiable (T) -> @differentiable (U) -> V {
2473-
{ x in { y in f(x, y) } }
2474-
}
2475-
```
2476-
2477-
However, the compiler does not support currying today due to known
2478-
type-theoretical constraints and implementation complexity regarding
2479-
differentiating a closure with respect to the values it captures. Fortunately,
2480-
we have a formally proven solution in the works, but we would like to defer this
2481-
to a future proposal since it is purely additive to the existing semantics.
2482-
24832567
### Higher-order differentiation
24842568

24852569
Distinct from differentiation of higher-order functions, higher-order
@@ -2528,9 +2612,7 @@ func valueWithDifferential<T: FloatingPoint, U: Differentiable>(
25282612

25292613
To differentiate `valueWithDifferential`, we need to be able to differentiate
25302614
its return value, a tuple of the original value and the differential, with
2531-
respect to its `x` argument. Since the return type contains a function,
2532-
[differentiation of higher-order functions](#differentiation-of-higher-order-functions)
2533-
is required for differentiating this differential operator.
2615+
respect to its `x` argument.
25342616

25352617
A kneejerk solution is to differentiate derivative functions generated by the
25362618
differentiation transform at compile-time, but this leads to problems. For

0 commit comments

Comments
 (0)