Skip to content

Commit 52b97b2

Browse files
committed
[AutoDiff] Move stdlib sources to stdlib/public/core/Differentiation.
Move differentiable-programming-related stdlib sources to `stdlib/public/core/Differentiation`. Related master branch PR: swiftlang#27511. master branch will have a `_Differentiation` support library containing the `Differentiable` protocol and related APIs. On tensorflow branch, the Swift source files in `stdlib/public/core/Differentiation` will be directly built as part of swiftCore for simplicity. Swift for TensorFlow users can continue to use the `Differentiable` protocol and related APIs without adding `import _Differentiation`. Rename `protocol _Differentiable` back to `protocol Differentiable`.
1 parent c5b5e4a commit 52b97b2

File tree

10 files changed

+151
-4
lines changed

10 files changed

+151
-4
lines changed

include/swift/AST/KnownIdentifiers.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ IDENTIFIER(decode)
5353
IDENTIFIER(decodeIfPresent)
5454
IDENTIFIER(Decoder)
5555
IDENTIFIER(decoder)
56+
IDENTIFIER_(Differentiation)
5657
IDENTIFIER(dynamicallyCall)
5758
IDENTIFIER(dynamicMember)
5859
IDENTIFIER(Element)

include/swift/AST/KnownProtocols.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ PROTOCOL_(DestructorSafeContainer)
9393

9494
PROTOCOL(StringInterpolationProtocol)
9595

96-
PROTOCOL_(Differentiable)
96+
PROTOCOL(Differentiable)
9797

9898
EXPRESSIBLE_BY_LITERAL_PROTOCOL(ExpressibleByArrayLiteral, "Array", false)
9999
EXPRESSIBLE_BY_LITERAL_PROTOCOL(ExpressibleByBooleanLiteral, "BooleanLiteralType", true)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#===--- CMakeLists.txt - Differentiable programming support library ------===#
2+
#
3+
# This source file is part of the Swift.org open source project
4+
#
5+
# Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors
6+
# Licensed under Apache License v2.0 with Runtime Library Exception
7+
#
8+
# See https://swift.org/LICENSE.txt for license information
9+
# See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
#
11+
#===----------------------------------------------------------------------===#
12+
13+
# SWIFT_ENABLE_TENSORFLOW
14+
# NOTE: This CMakeLists.txt file is currently used only on master branch, not
15+
# on tensorflow branch. Instead, on tensorflow branch, the Swift source files
16+
# in this directory are directly built as part of swiftCore: see
17+
# stdlib/public/core/CMakeLists.txt.
18+
# SWIFT_ENABLE_TENSORFLOW END
19+
20+
add_swift_target_library(swift_Differentiation ${SWIFT_STDLIB_LIBRARY_BUILD_TYPES} IS_STDLIB
21+
Differentiable.swift
22+
23+
SWIFT_COMPILE_FLAGS ${SWIFT_STANDARD_LIBRARY_SWIFT_FLAGS}
24+
LINK_FLAGS "${SWIFT_RUNTIME_SWIFT_LINK_FLAGS}"
25+
INSTALL_IN_COMPONENT stdlib)
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
//===--- Differentiable.swift ---------------------------------*- swift -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// This file defines the Differentiable protocol, used by the experimental
14+
// differentiable programming project. This API is not stable and subject to
15+
// change.
16+
//
17+
// Please see forum discussion for more information about the differentiable
18+
// programming project:
19+
// https://forums.swift.org/t/differentiable-programming-mega-proposal/28547
20+
//
21+
//===----------------------------------------------------------------------===//
22+
23+
/// A type that mathematically represents a differentiable manifold whose
24+
/// tangent spaces are finite-dimensional.
25+
public protocol Differentiable {
26+
/// A type representing a differentiable value's derivatives.
27+
///
28+
/// Mathematically, this is equivalent to the tangent bundle of the
29+
/// differentiable manifold represented by the differentiable type.
30+
associatedtype TangentVector: Differentiable & AdditiveArithmetic
31+
where TangentVector.TangentVector == TangentVector
32+
33+
/// Moves `self` along the given direction. In Riemannian geometry, this is
34+
/// equivalent to exponential map, which moves `self` on the geodesic surface
35+
/// along the given tangent vector.
36+
mutating func move(along direction: TangentVector)
37+
38+
// SWIFT_ENABLE_TENSORFLOW
39+
/// A tangent vector such that `move(along: zeroTangentVector)` will not
40+
/// modify `self`.
41+
/// - Note: `zeroTangentVector` can be `TangentVector.zero` in most cases,
42+
/// but types whose tangent vectors depend on instance properties of `self`
43+
/// need to provide a different implementation. For example, the tangent
44+
/// vector of an `Array` depends on the array's `count`.
45+
@available(*, deprecated, message: """
46+
`zeroTangentVector` derivation has not been implemented; do not use \
47+
this property
48+
""")
49+
var zeroTangentVector: TangentVector { get }
50+
// SWIFT_ENABLE_TENSORFLOW END
51+
}
52+
53+
public extension Differentiable where TangentVector == Self {
54+
@_alwaysEmitIntoClient
55+
mutating func move(along direction: TangentVector) {
56+
self += direction
57+
}
58+
}
59+
60+
// SWIFT_ENABLE_TENSORFLOW
61+
public extension Differentiable {
62+
// This is a temporary solution that allows us to add `zeroTangentVector`
63+
// without implementing derived conformances. This property is marked
64+
// unavailable because it will produce incorrect results when tangent vectors
65+
// depend on instance properties of `self`.
66+
// FIXME: Implement derived conformance and remove this default
67+
// implementation.
68+
var zeroTangentVector: TangentVector { .zero }
69+
}
70+
// SWIFT_ENABLE_TENSORFLOW END

stdlib/public/core/CMakeLists.txt

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -197,15 +197,16 @@ set(SWIFTLIB_ESSENTIAL_GYB_SOURCES
197197
UnsafeRawBufferPointer.swift.gyb
198198
)
199199

200+
# SWIFT_ENABLE_TENSORFLOW
200201
# Compile differentiable programming sources only if enabled.
201202
set(SWIFTLIB_DIFFERENTIABLE_PROGRAMMING_SOURCES)
202203
if(SWIFT_ENABLE_EXPERIMENTAL_DIFFERENTIABLE_PROGRAMMING)
203204
list(APPEND SWIFTLIB_DIFFERENTIABLE_PROGRAMMING_SOURCES
204-
Differentiable.swift
205-
# SWIFT_ENABLE_TENSORFLOW
206-
DifferentiationSupport.swift)
205+
../Differentiation/Differentiable.swift
206+
../Differentiation/DifferentiationSupport.swift)
207207
message(STATUS "Differentiable programming standard library additions enabled.")
208208
endif()
209+
# SWIFT_ENABLE_TENSORFLOW END
209210

210211
# The complete list of sources in the core standard library. Includes
211212
# all the essential sources listed above.
@@ -225,7 +226,9 @@ set(SWIFTLIB_SOURCES
225226
VarArgs.swift
226227
Zip.swift
227228
"${SWIFT_SOURCE_DIR}/stdlib/linker-support/magic-symbols-for-install-name.c"
229+
# SWIFT_ENABLE_TENSORFLOW
228230
${SWIFTLIB_DIFFERENTIABLE_PROGRAMMING_SOURCES}
231+
# SWIFT_ENABLE_TENSORFLOW END
229232
)
230233

231234
set(SWIFTLIB_GYB_SOURCES

test/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,9 +134,11 @@ normalize_boolean_spelling(SWIFT_AST_VERIFIER)
134134
normalize_boolean_spelling(SWIFT_ASAN_BUILD)
135135
normalize_boolean_spelling(SWIFT_BUILD_SYNTAXPARSERLIB)
136136
normalize_boolean_spelling(SWIFT_ENABLE_SOURCEKIT_TESTS)
137+
normalize_boolean_spelling(SWIFT_ENABLE_EXPERIMENTAL_DIFFERENTIABLE_PROGRAMMING)
137138
# SWIFT_ENABLE_TENSORFLOW
138139
normalize_boolean_spelling(SWIFT_ENABLE_TENSORFLOW)
139140
normalize_boolean_spelling(SWIFT_ENABLE_TENSORFLOW_GPU)
141+
# SWIFT_ENABLE_TENSORFLOW END
140142
is_build_type_optimized("${SWIFT_STDLIB_BUILD_TYPE}" SWIFT_OPTIMIZED)
141143

142144
set(profdata_merge_worker
@@ -317,6 +319,10 @@ _Block_release(void) { }\n")
317319

318320
list(APPEND LIT_ARGS "--xunit-xml-output=${SWIFT_TEST_RESULTS_DIR}/lit-tests.xml")
319321

322+
if(SWIFT_ENABLE_EXPERIMENTAL_DIFFERENTIABLE_PROGRAMMING)
323+
list(APPEND LIT_ARGS "--param" "differentiable_programming")
324+
endif()
325+
320326
foreach(test_subset ${TEST_SUBSETS})
321327
set(directories)
322328
set(dependencies ${test_dependencies})
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// RUN: %target-typecheck-verify-swift
2+
// REQUIRES: differentiable_programming
3+
4+
import _Differentiation
5+
6+
// Test conformances.
7+
8+
struct Wrapper<T> {
9+
var value: T
10+
}
11+
extension Wrapper: Equatable where T: Equatable {}
12+
extension Wrapper: AdditiveArithmetic where T: AdditiveArithmetic {
13+
static var zero: Self {
14+
Wrapper(value: T.zero)
15+
}
16+
static func + (lhs: Self, rhs: Self) -> Self {
17+
return Wrapper(value: lhs.value + rhs.value)
18+
}
19+
static func - (lhs: Self, rhs: Self) -> Self {
20+
return Wrapper(value: lhs.value + rhs.value)
21+
}
22+
}
23+
extension Wrapper: Differentiable where T: Differentiable {
24+
typealias TangentVector = Wrapper<T.TangentVector>
25+
mutating func move(along direction: TangentVector) {
26+
value.move(along: direction.value)
27+
}
28+
}
29+
30+
// Test conformances for standard library types.
31+
32+
extension Float: Differentiable {
33+
public typealias TangentVector = Self
34+
}

test/lit.cfg

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,10 @@ swift_version = lit_config.params.get('swift-version',
345345
lit_config.note('Compiling with -swift-version ' + swift_version)
346346
config.swift_test_options = '-swift-version ' + swift_version
347347

348+
differentiable_programming = lit_config.params.get('differentiable_programming', None)
349+
if differentiable_programming is not None:
350+
config.available_features.add('differentiable_programming')
351+
348352
# SWIFT_ENABLE_TENSORFLOW
349353
swift_tensorflow_test_run_extra_options = ''
350354
swift_tensorflow_extra_options = ''
@@ -363,6 +367,7 @@ else:
363367
config.substitutions.append( ('%filecheck-tensorflow-extra-options', '') )
364368
config.substitutions.append( ('%swift-tensorflow-extra-options', swift_tensorflow_extra_options) )
365369
config.substitutions.append( ('%swift-tensorflow-test-run-extra-options', swift_tensorflow_test_run_extra_options) )
370+
# SWIFT_ENABLE_TENSORFLOW END
366371

367372
test_options = os.environ.get('SWIFT_TEST_OPTIONS')
368373
if test_options:

test/lit.site.cfg.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,9 @@ if '@SWIFT_INCLUDE_TOOLS@' == 'TRUE':
126126
if "@SWIFT_SOURCEKIT_USE_INPROC_LIBRARY@" == "TRUE":
127127
config.available_features.add('sourcekit_use_inproc_library')
128128

129+
if "@SWIFT_ENABLE_EXPERIMENTAL_DIFFERENTIABLE_PROGRAMMING@" == "TRUE":
130+
config.available_features.add('differentiable_programming')
131+
129132
# Let the main config do the real work.
130133
if config.test_exec_root is None:
131134
config.test_exec_root = os.path.dirname(os.path.realpath(__file__))

0 commit comments

Comments
 (0)