Commit Graph

35 Commits

Author SHA1 Message Date
Dan Zheng
b4fa7e0027 [AutoDiff] Support direct init reference differentiation.
Support `@differentiable` function conversion for `init` references, in
addition to `func` references and literal closures. Minor usability improvement.

Resolves SR-12562.
2020-04-10 01:26:34 -07:00
Marc Rasi
7abf8ae305 actually set the lazy resolver 2020-04-07 15:05:27 -07:00
Marc Rasi
2d1436e8d2 fix SR-12526 test 2020-04-07 10:26:57 -07:00
Dan Zheng
52b771dfe4 [AutoDiff] Add SR-12526 negative test.
Add negative test for SR-12526: `@derivative` attribute cross-module
deserialization crash.
2020-04-06 02:36:18 -07:00
Dan Zheng
0c1d4b5adf [AutoDiff] Enable cross-file derivative registration.
Lift temporary cross-file derivative registration restriction.

`@derivative` attribute type-checking simplications coming soon: TF-1099.
Original function and derivative function must have same access level, with one
exception: public original functions may have internal `@usableFromInline`
derivatives.
2020-04-06 02:36:02 -07:00
Dan Zheng
172d57fa93 [AutoDiff] Add @_exported import _Differentiation test. (#30769)
Verify that importing a module with `@_exported import _Differentiation`
enables differentiable programming. This behavior is desirable.
2020-04-02 10:19:56 -07:00
Dan Zheng
1308fc69c5 [AutoDiff] Simplify conditions enabling differentiable programming. (#30765)
Previously, two conditions were necessary to enable differentiable programming:
- Using the `-enable-experimental-differentiable-programming` frontend flag.
- Importing the `_Differentiation` module.

Importing the `_Differentiation` module is the true condition because it
contains the required compiler-known `Differentiable` protocol. The frontend
flag is redundant and cumbersome.

Now, the frontend flag is removed.
Importing `_Differentiation` is the only condition.
2020-04-02 03:24:03 -07:00
ematejska
9f0f92fa29 [AutoDiff upstream] Upstream @transpose attribute type-checking. (#30664)
The `@transpose` attribute registers a function as the transpose of another
function-like declaration: a `func`, `init`, `subscript`, or `var` computed
property declaration.

The `@transpose` attribute also has an optional `wrt:` clause specifying the
linearity parameters, i.e. the parameters that are transposed with respect to.
The linearity parameters must conform to the `Differentiable` protocol and
satisfy `Self == TangentVector`.

If the `wrt:` clause is unspecified, the linearity parameters are inferred to be
all parameters that conform to `Differentiable` and that satisfy
`Self == TangentVector`.

`@transpose` attribute type-checking verifies that the type of the transpose
function declaration is consistent with the type of the referenced original
declaration and the linearity parameters.

Resolves TF-830.
2020-03-27 11:22:21 -07:00
Dan Zheng
bbe86e908d [AutoDiff upstream] Add Differentiable protocol derived conformances. (#30671)
Add `AdditiveArithmetic` derived conformances for structs and classes, gated by
the `-enable-experimental-differentiable-programming` flag.

Structs and classes whose stored properties all conform to `Differentiable` can
derive `Differentiable`:

- `associatedtype TangentVector: Differentiable & AdditiveArithmetic`
  - Member `TangentVector` structs are synthesized whose stored properties are
    all `var` stored properties that conform to `Differentiable` and that are
    not `@noDerivative`.
- `mutating func move(along: TangentVector)`

The `@noDerivative` attribute may be declared on stored properties to opt out of
inclusion in synthesized `TangentVector` structs.

Some stored properties cannot be used in `TangentVector` struct synthesis and
are implicitly marked as `@noDerivative`, with a warning:

- `let` stored properties.
  - These cannot be updated by `mutating func move(along: TangentVector)`.
- Non-`Differentiable`-conforming stored properties.

`@noDerivative` also implies `@_semantics("autodiff.nonvarying")`, which is
relevant for differentiable activity analysis.

Add type-checking and SILGen tests.

Resolves TF-845.
2020-03-27 06:40:04 -07:00
marcrasi
f6562d3a67 [AutoDiff upstream] differentiable function conversion pipeline (#30660)
Add the `@differentiable` function conversion pipeline:

- New expressions that convert between `@differentiable`,
  `@differentiable(linear)`, and non-`@differentiable` functions:
  - `DifferentiableFunction`
  - `LinearFunction`
  - `DifferentiableFunctionExtractOriginal`
  - `LinearFunctionExtractOriginal`
  - `LinearToDifferentiableFunction`
- All the AST handling (e.g. printing) necessary for those expressions.
- SILGen for those expressions.
- CSApply code that inserts these expressions to implicitly convert between
  the various function types.
- Sema tests for the implicit conversions.
- SILGen tests for the SILGen of these expressions.

Resolves TF-833.
2020-03-27 01:27:39 -07:00
marcrasi
eae4c5eece [AutoDiff upstream] @differentiable function type sema (#30648)
Add type checking for `@differentiable` function types:
- Check that parameters and results conform to `Differentiable`.
- Implicitly conform parameters and results whose types are generic parameters
  to `Differentiable`.
- Upstream most of the differentiable_func_type_type_checking.swift test from
  `tensorflow` branch. A few function conversion tests have not been added
   because they depend on the `@differentiable` function conversion pipeline.

Diagnose gracefully when the `Differentiable` protocol is unavailable because
`_Differentiation` has not been imported.

Resolves TF-823 and TF-1219.
2020-03-26 23:28:02 -07:00
Dan Zheng
e5cb871428 [AutoDiff upstream] Add flag-gated AdditiveArithmetic derivation. (#30628)
Add `AdditiveArithmetic` derived conformances for structs, gated by the
`-enable-experimential-additive-arithmetic-derivation` flag.

Structs whose stored properties all conform to `AdditiveArithmetic` can derive
`AdditiveArithmetic`:
- `static var zero: Self`
- `static func +(lhs: Self, rhs: Self) -> Self`
- `static func -(lhs: Self, rhs: Self) -> Self`
- An "effective memberwise initializer":
  - Either a synthesized memberwise initializer or a user-defined initializer
    with the same type.

Effective memberwise initializers are used only by derived conformances for
`Self`-returning protocol requirements like `AdditiveArithmetic.+`, which
require memberwise initialization.

Resolves TF-844.
Unblocks TF-845: upstream `Differentiable` derived conformances.
2020-03-25 10:31:50 -07:00
Dan Zheng
07596cbc9b [AutoDiff upstream] Relax @differentiable for protocol witnesses. (#30629)
Previously, all witnesses of a `@differentiable` protocol requirement were
required to have the same attribute (or one with superset parameter indices).

However, this leads to many annotations on witnesses and is not ideal for
usability. `@differentiable` attributes are really only significant on
public witnesses, so that they are clearly `@differentiable` at a glance (in
source code, interface files, and API documentation), without looking through
protocol conformance hierarchies.

Now, only *public* witnesses of `@differentiable` protocol requirements are
required to have the same attribute (or one with superset parameter indices).
For less-visible witnesses, an implicit `@differentiable` attribute is created
with the same configuration as the requirement's.

Resolves TF-1117.
Upstreams #29771 from tensorflow branch.
2020-03-25 08:13:27 -07:00
marcrasi
1be86adbfc [AutoDiff] forbid derivative registration using @differentiable (#30001)
Delete `@differentiable` attribute `jvp:` and `vjp:` arguments for derivative
registration. `@derivative` attribute is now the canonical way to register
derivatives.

Resolves TF-1001.
2020-03-24 00:41:27 -07:00
Dan Zheng
6dd557a557 [AutoDiff] NFC: garden tests. (#30588)
Add test/AutoDiff/lit.local.cfg: run tests only when `differentiable_programming`
is enabled in lit. With this, individual tests no longer need
`REQUIRES: differentiable_programming`.

Move multi-functionality SIL tests from test/AutoDiff/SIL/Serialization to
test/AutoDiff/SIL.

Garden test filenames.
2020-03-23 15:22:27 -07:00
Dan Zheng
697c722a5f [AutoDiff] Type-checking support for inout parameter differentiation. (#29959)
Semantically, an `inout` parameter is both a parameter and a result.

`@differentiable` and `@derivative` attributes now support original functions
with one "semantic result": either a formal result or an `inout` parameter.

Derivative typing rules for functions with `inout` parameters are now defined.

The differential/pullback type of a function with `inout` differentiability
parameters also has `inout` parameters. This is ideal for performance.

Differential typing rules:
- Case 1: original function has no `inout` parameters.
  - Original:     `(T0, T1, ...) -> R`
  - Differential: `(T0.Tan, T1.Tan, ...) -> R.Tan`
- Case 2: original function has a non-wrt `inout` parameter.
  - Original:     `(T0, inout T1, ...) -> Void`
  - Differential: `(T0.Tan, ...) -> T1.Tan`
- Case 3: original function has a wrt `inout` parameter.
  - Original:     `(T0, inout T1, ...) -> Void`
  - Differential: `(T0.Tan, inout T1.Tan, ...) -> Void`

Pullback typing rules:
- Case 1: original function has no `inout` parameters.
  - Original: `(T0, T1, ...) -> R`
  - Pullback: `R.Tan -> (T0.Tan, T1.Tan, ...)`
- Case 2: original function has a non-wrt `inout` parameter.
  - Original: `(T0, inout T1, ...) -> Void`
  - Pullback: `(T1.Tan) -> (T0.Tan, ...)`
- Case 3: original function has a wrt `inout` parameter.
  - Original: `(T0, inout T1, ...) -> Void`
  - Pullback: `(inout T1.Tan) -> (T0.Tan, ...)`

Resolves TF-1164.
2020-02-21 09:47:53 -08:00
swift-ci
5e030b57a2 Merge pull request #29918 from dan-zheng/derivative-attr-diagnostics 2020-02-19 23:26:54 -08:00
Dan Zheng
e5e9fce8bf [AutoDiff upstream] Upstream attribute type-checking changes. (#29945)
- Support `@differentiable` and `@derivative` attributes for original
  initializers in final classes. Reject original initializers in non-final
  classes.
- Synchronize tests.
2020-02-19 21:17:45 -08:00
Dan Zheng
469ecb640f Improve @derivative type-checking diagnostics order.
Attempt to look up original function before checking whether the `value:` result
conforms to `Differentiable`.

This improves diagnostics: "original function not found" should be diagnosed as
early as possible.
2020-02-19 09:54:31 -08:00
Dan Zheng
2c70f0ae6c [AutoDiff] Improve @derivative attribute diagnostics.
Previously, `@derivative` attribute type-checking produced a confusing error
referencing unbound types `T` and `U`:

```
'@derivative(of:)' attribute requires function to return a two-element tuple of
type '(value: T..., pullback: (U.TangentVector) -> T.TangentVector...)' or
'(value: T..., differential: (T.TangentVector...) -> U.TangentVector)'
```

Now, the error is less confusing:

```
'@derivative(of:)' attribute requires function to return a two-element tuple;
first element must have label 'value:' and second element must have label
'pullback:' or 'differential:'
```
2020-02-19 04:48:27 +00:00
Dan Zheng
aabc849c9e [AutoDiff] Add @differentiable fix-it for protocols/classes. (#29332)
For protocol requirements and class members with `@differentiable` attribute,
conforming types and subclasses must have the same `@differentiable` attribute
(or one with a superset of differentiability parameters) on implementing/
overriding declarations.

For implementing/overriding declarations that are missing a `@differentiable`
attribute, emit a fix-it that adds the missing attribute.

Resolves TF-1118.
2020-01-21 20:01:38 -08:00
Dan Zheng
44d937d7c2 [AutoDiff upstream] Add @differentiable declaration attribute type-checking. (#29231)
The `@differentiable` attribute marks a function as differentiable.

Example:
```
@differentiable(wrt: x, jvp: derivativeFoo where T: Differentiable)
func id<T>(_ x: T) -> T { x }
```

The `@differentiable` attribute has an optional `wrt:` clause specifying the
parameters that are differentiated "with respect to", i.e. the differentiability
parameters. The differentiability parameters must conform to the
`Differentiable` protocol.

If the `wrt:` clause is unspecified, the differentiability parameters are
currently inferred to be all parameters that conform to `Differentiable`.

The `@differentiable` attribute also has optional `jvp:` and `vjp:` labels
for registering derivative functions. These labels are deprecated in favor of
the `@derivative` attribute and will be removed soon.

The `@differentiable` attribute also has an optional `where` clause, specifying
extra differentiability requirements for generic functions.

The `@differentiable` attribute is gated by the
`-enable-experimental-differentiable-programming` flag.

Code changes:
- Add `DifferentiableAttributeTypeCheckRequest`.
  - Currently, the request returns differentiability parameter indices, while
    also resolving `JVPFunction`, `VJPFunction`, and
    `DerivativeGenericSignature` and mutating them in-place in
    `DifferentiableAttr`. This was the simplest approach that worked without
    introducing request cycles.
- Add "is type-checked" bit to `DifferentiableAttr`.
  - Alternatively, I tried changing `DifferentiableAttributeTypeCheckRequest` to
    use `CacheKind::Cache` instead of `CacheKind::SeparatelyCached`, but it did
    not seem to work: `@differentiable` attributes in non-primary-files were
    left unchecked.

Type-checking rules (summary):
- `@differentiable` attribute must be declared on a function-like "original"
  declaration: `func`, `init`, `subscript`, `var` (computed properties only).
- Parsed differentiability parameters must be valid (if they exist).
- Parsed `where` clause must be valid (if it exists).
- Differentiability parameters must all conform to `Differentiable`.
- Original result must all conform to `Differentiable`.
- If JVP/VJP functions are specified, they must match the expected type.
  - `@differentiable(jvp:vjp:)` for derivative registration is deprecated in
    favor of `@derivative` attribute, and will be removed soon.
- Duplicate `@differentiable` attributes with the same differentiability
  parameters are invalid.
- For protocol requirements and class members with `@differentiable` attribute,
  conforming types and subclasses must have the same `@differentiable` attribute
  (or one with a superset of differentiability parameter indices) on
  implementing/overriding declarations.
2020-01-19 12:23:04 -08:00
Dan Zheng
29465f82ad Add standalone test. 2020-01-06 18:29:26 -08:00
Marc Rasi
d69e892f03 [AutoDiff upstream] forbid @derivative of protocol req 2020-01-06 15:57:35 -08:00
Karoy Lorentey
d61de7d8a2 Merge pull request #28893 from apple/revert-28882-master
Revert "[test] Mark _Differentiable tests as unsupported in Swift-in-the-OS configurations"
2019-12-19 21:08:02 -08:00
Dan Zheng
14ee6c5d1c [AutoDiff] Enable @derivative attribute qualified declaration names. (#28892)
Enable qualified declaration names in `@derivative` attribute, just like
`@transpose` attribute.

`DerivativeAttr` now stores a base type `TypeRepr *`, which is non-null for
parsed attributes that reference a qualified original declaration.

Add `TypeResolutionFlags::AllowModule` flag to enable module lookup via
`TypeChecker::lookupMember` given a `ModuleType`.

Add tests for type-qualified and module-qualified declaration names.

Resolves TF-1058.
2019-12-19 21:06:20 -08:00
Karoy Lorentey
f2ed81b763 Revert "[test] Mark _Differentiable tests as unsupported in Swift-in-the-OS configurations" 2019-12-19 19:16:00 -08:00
swift-ci
ec0a2cae9d Merge pull request #28278 from marcrasi/ast-nondiff 2019-12-19 14:06:48 -08:00
Karoy Lorentey
216d02f84d [test] Mark _Differentiable tests as unsupported in Swift-in-the-OS configuration
The new _Differentiable module is not available in any shipping OS release, but its public API currently doesn’t have availability, either.

Temporarily disable tests that import it when we’re testing with OS-provided libraries.

The typecheck test test/AutoDiff/stdlib/differentiable_protocol.swift imports _Differentable but still somehow succeeds in these configs, so leave that one enabled.

rdar://57975086
2019-12-19 12:53:23 -08:00
Marc Rasi
72194c547b Merge branch 'master' into ast-nondiff 2019-12-18 17:25:09 -08:00
Dan Zheng
1d66571bc7 [AutoDiff upstream] @derivative attribute type-checking fixes.
Upstream `@derivative` attribute type-checking fixes regarding derivative
generic signatures with all concrete generic parameters.

Cherry-picked from:
- https://github.com/apple/swift/pull/28762
- https://github.com/apple/swift/pull/28772
2019-12-18 19:45:38 +00:00
Dan Zheng
bb1052ca3e [AutoDiff upstream] Upstream @derivative attribute type-checking. (#28738)
The `@derivative` attribute registers a function as a derivative of another
function-like declaration: a `func`, `init`, `subscript`, or `var` computed
property declaration.

The `@derivative` attribute also has an optional `wrt:` clause specifying the
parameters that are differentiated "with respect to", i.e. the differentiation
parameters. The differentiation parameters must conform to the `Differentiable`
protocol.

If the `wrt:` clause is unspecified, the differentiation parameters are inferred
to be all parameters that conform to `Differentiable`.

`@derivative` attribute type-checking verifies that the type of the derivative
function declaration is consistent with the type of the referenced original
declaration and the differentiation parameters.

The `@derivative` attribute is gated by the
`-enable-experimental-differentiable-programming` flag.

Resolves TF-829.
2019-12-12 18:18:18 -08:00
Marc Rasi
6e559ab8fa rename nondiff => noDerivative 2019-11-15 16:36:26 -08:00
Marc Rasi
f5677cbe42 add @nondiff to AnyFunctionType params 2019-11-14 16:49:22 -08:00
marcrasi
ce756e3189 [AutoDiff upstream] parsing for @differentiable function type (#27708)
Adds parsing for a type attribute `@differentiable`, which is optionally allowed to have argument `@differentiable(linear)`.

The typechecker currently rejects all uses of `@differentiable` with "error: attribute does not apply to type". Future work (https://bugs.swift.org/browse/TF-871 https://bugs.swift.org/browse/TF-873) will update the typechecker to allow this attribute in places where it is allowed.

Resolves https://bugs.swift.org/browse/TF-822.
2019-11-04 23:40:04 -08:00