* Attempt at a patch for SR-14053 and SR-14218, based on Dan Zheng's initial fix.
* Incorporated Dan's cleanup suggestions.
* Converting a bool SmallVector to a SmallBitVector.
* Testing if Windows issues with this test are due to runtime support.
* Simplifying test case.
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.