Repurpose mangling operator `Y` as an umbrella operator that covers new attributes on function types. Free up operators `J`, `j`, and `k`.
```
async ::= 'Ya' // 'async' annotation on function types
sendable ::= 'Yb' // @Sendable on function types
throws ::= 'K' // 'throws' annotation on function types
differentiable ::= 'Yjf' // @differentiable(_forward) on function type
differentiable ::= 'Yjr' // @differentiable(reverse) on function type
differentiable ::= 'Yjd' // @differentiable on function type
differentiable ::= 'Yjl' // @differentiable(_linear) on function type
```
Resolves rdar://76299796.
`@noDerivative` was not mangled in function types, and was resolved incorrectly when there's an ownership specifier. It is fixed by this patch with the following changes:
* Add `NoDerivative` demangle node represented by a `k` operator.
```
list-type ::= type identifier? 'k'? 'z'? 'h'? 'n'? 'd'? // type with optional label, '@noDerivative', inout convention, shared convention, owned convention, and variadic specifier
```
* Fix `NoDerivative`'s overflown offset in `ParameterTypeFlags` (`7` -> `6`).
* In type decoder and type resolver where attributed type nodes are processed, add support for nested attributed nodes, e.g. `inout @noDerivative T`.
* Add `TypeResolverContext::InoutFunctionInput` so that when we resolve an `inout @noDerivative T` parameter, the `@noDerivative T` checking logic won't get a `TypeResolverContext::None` set by the caller.
Resolves rdar://75916833.
This currently fails when run on the macOS 10.14.4 stdlib:
```
[ RUN ] FunctionTypeMetadata.Reflect differentiable function type
stdout>>> check failed at /Users/buildslave/jenkins/workspace/fs-swift-main-tools_RA-stdlib_RA-macOS-swift-in-OS-10.14.4/swift/test/AutoDiff/validation-test/function_type_metadata.swift, line 10
stdout>>> expected: "@differentiable(reverse) (Swift.Float) -> Swift.Float" (of type Swift.String)
stdout>>> actual: "-3.8442426e-13" (of type Swift.String)
stderr>>> CRASHED: SIGSEGV
the test crashed unexpectedly
[ FAIL ] FunctionTypeMetadata.Reflect differentiable function type
```
rdar://76039256
* Move differentiability kinds from target function type metadata to trailing objects so that we don't exhaust all remaining bits of function type metadata.
* Differentiability kind is now stored in a tail-allocated word when function type flags say it's differentiable, located immediately after the normal function type metadata's contents (with proper alignment in between).
* Add new runtime function `swift_getFunctionTypeMetadataDifferentiable` which handles differentiable function types.
* Fix mangling of different differentiability kinds in function types. Mangle it like `ConcurrentFunctionType` so that we can drop special cases for escaping functions.
```
function-signature ::= params-type params-type async? sendable? throws? differentiable? // results and parameters
...
differentiable ::= 'jf' // @differentiable(_forward) on function type
differentiable ::= 'jr' // @differentiable(reverse) on function type
differentiable ::= 'jd' // @differentiable on function type
differentiable ::= 'jl' // @differentiable(_linear) on function type
```
Resolves rdar://75240064.
Tests for false positive precondition triggered by a .zero gradient, i.e. empty [] array, back-propagated through concatenation and move methods
Implements a simplified reproducer of SR-14297
Rename `move(along:)` to `move(by:)` based on the proposal feedback. The main argument for the change is that tangent vectors specify both a direction and a magnitude, whereas `along:` does not indicate that `self` is being moved by the specified magnitude.
Compiler:
- Add `Forward` and `Reverse` to `DifferentiabilityKind`.
- Expand `DifferentiabilityMask` in `ExtInfo` to 3 bits so that it now holds all 4 cases of `DifferentiabilityKind`.
- Parse `@differentiable(reverse)` and `@differentiable(_forward)` declaration attributes and type attributes.
- Emit a warning for `@differentiable` without `reverse`.
- Emit an error for `@differentiable(_forward)`.
- Rename `@differentiable(linear)` to `@differentiable(_linear)`.
- Make `@differentiable(reverse)` type lowering go through today's `@differentiable` code path. We will specialize it to reverse-mode in a follow-up patch.
ABI:
- Add `Forward` and `Reverse` to `FunctionMetadataDifferentiabilityKind`.
- Extend `TargetFunctionTypeFlags` by 1 bit to store the highest bit of differentiability kind (linear). Note that there is a 2-bit gap in `DifferentiabilityMask` which is reserved for `AsyncMask` and `ConcurrentMask`; `AsyncMask` is ABI-stable so we cannot change that.
_Differentiation module:
- Replace all occurrences of `@differentiable` with `@differentiable(reverse)`.
- Delete `_transpose(of:)`.
Resolves rdar://69980056.
This disables 4 tests:
- DerivativeRegistrationTests.NonCanonicalizedGenericSignatureComparison
- Reabstraction.diff param generic => concrete
- Reabstraction.diff param and nondiff param generic => concrete
- Reabstraction.result generic => concrete
Simultaneously, enable the remainder of the auto-diff test suite on
Windows. These tests fail on Windows due to an invalid parameter during
the reabstraction of the generic differentiable parameters. The
remainder of the auto-differentiation tests pass on all the platforms.
- `Mangle::ASTMangler::mangleAutoDiffDerivativeFunction()` and `Mangle::ASTMangler::mangleAutoDiffLinearMap()` accept original function declarations and return a mangled name for a derivative function or linear map. This is called during SILGen and TBDGen.
- `Mangle::DifferentiationMangler` handles differentiation function mangling in the differentiation transform. This part is necessary because we need to perform demangling on the original function and remangle it as part of a differentiation function mangling tree in order to get the correct substitutions in the mangled derivative generic signature.
A mangled differentiation function name includes:
- The original function.
- The differentiation function kind.
- The parameter indices for differentiation.
- The result indices for differentiation.
- The derivative generic signature.
Enable `@differentiable` attribute on setters of properties and
subscripts in `Differentiable`-conforming types.
Add automatically-differentiated `@differentiable` setter test.
Resolves TF-1166.
The test relies on the module name being `null`. This is implied by the
`-o /dev/null`. However, that is not guaranteed. Explicitly use the
desired module name.
This replaces swiftMSVCRT with swiftCRT. The big difference here is
that the `visualc` module is no longer imported nor exported. The
`visualc` module remains in use for a singular test wrt availability,
but this should effectively remove the need for the `visualc` module.
The difference between the MSVCRT and ucrt module was not well
understood by most. MSVCRT provided ucrt AND visualc, combining pieces
of the old MSVCRT and the newer ucrt. The ucrt module is what you
really wanted most of the time, however, would need to use MSVCRT for
the convenience aliases for type-generic math and the deprecated math
constants.
Unfortunately, we cannot shadow the `ucrt` module and create a Swift SDK
overlay for ucrt as that seems to result in circular dependencies when
processing the `_Concurrency` module.
Although this makes using the C library easier for most people, it has a
more important subtle change: it cleaves the dependency on visualc.
This means that this enables use of Swift without Visual Studio for the
singular purpose of providing 3 header files. Additionally, it removes
the need for the installation of 2 of the 4 support files. This greatly
simplifies the deployment process on Windows.
Previously, `LinearMapInfo::shouldDifferentiateInstruction` had a special case
for `copy_value`, returning true for `copy_value` instructions with an active
operand.
This is unexpected and led to "leaked owned value" ownership verification
failures due to unnecessarily cloned `copy_value` instructions during
differential generation.
Now, the special case is removed, fixing the failures.
`shouldDifferentiateInstruction` returns true for `copy_value` instructions
whose operand and result are both active.
Resolves SR-13530.
Splits the large `forward_mode.swift` test file into 3 files:
- `forward_mode_simple.swift`
- `forward_mode_array.swift`
- `forward_mode_simd.swift`
This significantly speeds up testing time when tests are run in parallel.
Fixes foward-mode crashed related to:
- Missing tangent buffers for non-wrt `inout` parameters.
- Tangent buffers not being initialized due to the corresponding original
buffer intialization instructions being non-active.
- Non-varied indirect results not being initialized.
- `emitDestroyValue` crashes due to `TangentVector` value category mismatch.
Resolves TF-984 and SR-13447.
Co-authored-by: Dan Zheng <danielzheng@google.com>
In `Differentiable` derived conformances, `let` properties are currently treated as if they had `@noDerivative` and excluded from the derived `Differentiable` conformance implementation. This is limiting to properties that have a non-mutating `move(along:)` (e.g. class properties), which can be mathematically treated as differentiable variables.
This patch changes the derived conformances behavior such that `let` properties will be included as differentiable variables if they have a non-mutating `move(along:)`. This unblocks the following code:
```swift
final class Foo: Differentiable {
let x: ClassStuff // Class type with a non-mutating 'move(along:)'
// Synthesized code:
// struct TangentVector {
// var x: ClassStuff.TangentVector
// }
// ...
// func move(along direction: TangentVector) {
// x.move(along: direction.x)
// }
}
```
Resolves SR-13474 (rdar://67982207).
Fix SIL pullback function type calculation: remap original `unowned` results to
the correct pullback parameter convention depending on the `TangentVector` type
lowering.
Make `PullbackCloner` visitors for the following instructions check and handle
tangent value categories: `struct`, `struct_extract`, `tuple`, `destructure_tuple`.
Add differentiation tests for `Optional` struct and class stored properties,
exercising the instruction visitors above.
Resolves SR-13430.
Adds forward mode support for `apply` instruction with `inout` arguments.
Example of supported code:
```
func add(_ x: inout Float, _ y: inout Float) -> Float {
var result = x
result += y
return result
}
print(differential(at: 1, 1, in: add)(1, 1)) // prints "2"
```
Add differentiation support for non-active `try_apply` SIL instructions.
Notable pullback generation changes:
* Original basic blocks are now visited in a different order:
* starting from the original basic block, all its predecessors
* are visited in a breadth-first search order. This ensures that
* all successors of any block are visited before the block itself.
Resolves TF-433.
Fix `Optional` differentiation crash for non-resilient `Wrapped` reference type.
Add `NonresilientTracked` type to `DifferentiationUnittest` for testing.
Resolves SR-13377.
Pullback generation now supports `switch_enum` and `switch_enum_addr`
instructions for `Optional`-typed operands.
Currently, the logic is special-cased to `Optional`, but may be generalized in
the future to support enums following general rules.
Fix SIL differential function type calculation to handle non-wrt `inout`
parameters.
Patch `SILFunctionType::getDifferentiabilityResultIndices` to prevent returning
empty result indices for `@differentiable` function types with no formal results
where all `inout` parameters are `@noDerivative`. TF-1305 tracks a robust fix.
Resolves SR-13305.
Exposes TF-1305: parameter/result differentiability hole for `inout` parameters.
Fix pullback generation for `unchecked_ref_cast` and `upcast` instructions
for class types with an address tangent value category.
Upstream end-to-end class differentiation tests.
* initial changes
* Add tests, undo unnecessary changes.
* Fixing up computed properties accessors and adding tests for getters.
* Adding nested type testcase
* Fixing error message for when accessor is referenced but not acutally found.
* Cleanup.
- Improve diagnostic message.
- Clean up code and tests.
- Delete unrelated nested type `@derivative` attribute tests.
* Temporarily disable class subscript setter derivative registration test.
Blocked by SR-13096.
* Adding libsyntax integration and fixing up an error message.
* Added a helper function for checking if the next token is an accessor label.
* Update utils/gyb_syntax_support/AttributeNodes.py
Co-authored-by: Dan Zheng <danielzheng@google.com>
* Update lib/Parse/ParseDecl.cpp
Co-authored-by: Dan Zheng <danielzheng@google.com>
* Add end-to-end derivative registration tests.
* NFC: run `git clang-format`.
* NFC: clean up formatting.
Re-apply `git clang-format`.
* Clarify parsing ambiguity FIXME comments.
* Adding couple of more testcases and fixing up error message for when accessor is not found on functions resolved.
* Update lib/Sema/TypeCheckAttr.cpp
Co-authored-by: Dan Zheng <danielzheng@google.com>
Co-authored-by: Dan Zheng <danielzheng@google.com>
Clean up a few general patterns that are now obviated by canImport
This aligns more generally with the cleanup that the Swift Package
Manager has already done in their automated XCTest-plumbing tool in
apple/swift-package-manager#1826.
Reverse-mode differentiation now supports `apply` instructions with multiple
active "semantic results" (formal results or `inout` parameters).
The "cannot differentiate through multiple results" non-differentiability error
is lifted.
Resolves TF-983.
Previously, PullbackEmitter assumed that original values' value category
matches their `TangentVector` types' value category. This was problematic
for loadable types with address-only `TangentVector` types.
Now, PullbackEmitter starts to support differentiation of loadable types with
address-only `TangentVector` types. This patch focuses on supporting and testing
class types, more support can be added incrementally.
Resolves TF-1149.