Skip to content
This repository was archived by the owner on Jul 1, 2023. It is now read-only.

Added support for the 'log1mexp' op and its VJP. #147

Merged
merged 29 commits into from
Jun 24, 2019

Conversation

eaplatanios
Copy link
Contributor

@eaplatanios eaplatanios commented May 30, 2019

This requires #145 and #146.

@eaplatanios
Copy link
Contributor Author

Added a test similar to #144, but we still need to figure out what to do about the .withoutDerivative(). Let's revisit this after #145 and #146 are merged because this depends on them.

@rxwei rxwei added the enhancement New feature or request label May 31, 2019
@rxwei rxwei self-assigned this May 31, 2019
@eaplatanios
Copy link
Contributor Author

@rxwei this is ready other than the function not being differentiable. If we figure out a withoutDerivative API I could make this differentiable, by using it on let isTooSmall = -x .< T(log(2.0)).

@rxwei
Copy link
Contributor

rxwei commented May 31, 2019

Let's add a global withoutDerivative(x) function in the TensorFlow module for now. We can move it to the standard library later.

@eaplatanios
Copy link
Contributor Author

@rxwei I implemented that, but I get the following error:

Assertion failed: (Index < Length && "Invalid index!"), function operator[], file /Users/eaplatanios/Development/GitHub/swift-source-temp/llvm/include/llvm/ADT/ArrayRef.h, line 241.
Stack dump:
0.      Program arguments: /Library/Developer/Toolchains/swift-tensorflow-LOCAL-2019-05-30-a.xctoolchain/usr/bin/swift -frontend -c /Users/eaplatanios/Development/GitHub/swift-apis/Sources/TensorFlow/Bindings/EagerExecution.swift /Users/eaplatanios/Development/GitHub/swift-apis/Sources/TensorFlow/Bindings/RawOpsGenerated.swift /Users/eaplatanios/Development/GitHub/swift-apis/Sources/TensorFlow/Bindings/TFTensorOperation.swift /Users/eaplatanios/Development/GitHub/swift-apis/Sources/TensorFlow/Context.swift /Users/eaplatanios/Development/GitHub/swift-apis/Sources/TensorFlow/Core/ArrayOps.swift /Users/eaplatanios/Development/GitHub/swift-apis/Sources/TensorFlow/Core/DataTypes.swift /Users/eaplatanios/Development/GitHub/swift-apis/Sources/TensorFlow/Core/DifferentialOperators.swift /Users/eaplatanios/Development/GitHub/swift-apis/Sources/TensorFlow/Core/Execution.swift /Users/eaplatanios/Development/GitHub/swift-apis/Sources/TensorFlow/Core/PythonConversion.swift /Users/eaplatanios/Development/GitHub/swift-apis/Sources/TensorFlow/Core/Runtime.swift /Users/eaplatanios/Development/GitHub/swift-apis/Sources/TensorFlow/Core/ShapedArray.swift /Users/eaplatanios/Development/GitHub/swift-apis/Sources/TensorFlow/Core/StringTensor.swift /Users/eaplatanios/Development/GitHub/swift-apis/Sources/TensorFlow/Core/Tensor.swift /Users/eaplatanios/Development/GitHub/swift-apis/Sources/TensorFlow/Core/TensorGroup.swift /Users/eaplatanios/Development/GitHub/swift-apis/Sources/TensorFlow/Core/TensorHandle.swift /Users/eaplatanios/Development/GitHub/swift-apis/Sources/TensorFlow/Core/TensorProtocol.swift /Users/eaplatanios/Development/GitHub/swift-apis/Sources/TensorFlow/Core/TensorShape.swift /Users/eaplatanios/Development/GitHub/swift-apis/Sources/TensorFlow/Core/Threading.swift /Users/eaplatanios/Development/GitHub/swift-apis/Sources/TensorFlow/Core/Utilities.swift /Users/eaplatanios/Development/GitHub/swift-apis/Sources/TensorFlow/Initializers.swift /Users/eaplatanios/Development/GitHub/swift-apis/Sources/TensorFlow/Layer.swift /Users/eaplatanios/Development/GitHub/swift-apis/Sources/TensorFlow/Layers/Convolutional.swift /Users/eaplatanios/Development/GitHub/swift-apis/Sources/TensorFlow/Layers/Core.swift /Users/eaplatanios/Development/GitHub/swift-apis/Sources/TensorFlow/Layers/Normalization.swift /Users/eaplatanios/Development/GitHub/swift-apis/Sources/TensorFlow/Layers/Pooling.swift /Users/eaplatanios/Development/GitHub/swift-apis/Sources/TensorFlow/Layers/Recurrent.swift /Users/eaplatanios/Development/GitHub/swift-apis/Sources/TensorFlow/Layers/Upsampling.swift /Users/eaplatanios/Development/GitHub/swift-apis/Sources/TensorFlow/Loss.swift /Users/eaplatanios/Development/GitHub/swift-apis/Sources/TensorFlow/Operators/Basic.swift /Users/eaplatanios/Development/GitHub/swift-apis/Sources/TensorFlow/Operators/Comparison.swift /Users/eaplatanios/Development/GitHub/swift-apis/Sources/TensorFlow/Operators/Dataset.swift -primary-file /Users/eaplatanios/Development/GitHub/swift-apis/Sources/TensorFlow/Operators/Math.swift -primary-file /Users/eaplatanios/Development/GitHub/swift-apis/Sources/TensorFlow/Operators/NN.swift -primary-file /Users/eaplatanios/Development/GitHub/swift-apis/Sources/TensorFlow/Optimizer.swift /Users/eaplatanios/Development/GitHub/swift-apis/Sources/TensorFlow/Random.swift -emit-module-path /Users/eaplatanios/Development/GitHub/swift-apis/.build/x86_64-apple-macosx/debug/TensorFlow.build/Operators/Math~partial.swiftmodule -emit-module-path /Users/eaplatanios/Development/GitHub/swift-apis/.build/x86_64-apple-macosx/debug/TensorFlow.build/Operators/NN~partial.swiftmodule -emit-module-path /Users/eaplatanios/Development/GitHub/swift-apis/.build/x86_64-apple-macosx/debug/TensorFlow.build/Optimizer~partial.swiftmodule -emit-module-doc-path /Users/eaplatanios/Development/GitHub/swift-apis/.build/x86_64-apple-macosx/debug/TensorFlow.build/Operators/Math~partial.swiftdoc -emit-module-doc-path /Users/eaplatanios/Development/GitHub/swift-apis/.build/x86_64-apple-macosx/debug/TensorFlow.build/Operators/NN~partial.swiftdoc -emit-module-doc-path /Users/eaplatanios/Development/GitHub/swift-apis/.build/x86_64-apple-macosx/debug/TensorFlow.build/Optimizer~partial.swiftdoc -emit-dependencies-path /Users/eaplatanios/Development/GitHub/swift-apis/.build/x86_64-apple-macosx/debug/TensorFlow.build/Operators/Math.d -emit-dependencies-path /Users/eaplatanios/Development/GitHub/swift-apis/.build/x86_64-apple-macosx/debug/TensorFlow.build/Operators/NN.d -emit-dependencies-path /Users/eaplatanios/Development/GitHub/swift-apis/.build/x86_64-apple-macosx/debug/TensorFlow.build/Optimizer.d -emit-reference-dependencies-path /Users/eaplatanios/Development/GitHub/swift-apis/.build/x86_64-apple-macosx/debug/TensorFlow.build/Operators/Math.swiftdeps -emit-reference-dependencies-path /Users/eaplatanios/Development/GitHub/swift-apis/.build/x86_64-apple-macosx/debug/TensorFlow.build/Operators/NN.swiftdeps -emit-reference-dependencies-path /Users/eaplatanios/Development/GitHub/swift-apis/.build/x86_64-apple-macosx/debug/TensorFlow.build/Optimizer.swiftdeps -target x86_64-apple-macosx10.10 -enable-objc-interop -sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk -I /Users/eaplatanios/Development/GitHub/swift-apis/.build/x86_64-apple-macosx/debug -F /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/Library/Frameworks -enable-testing -g -module-cache-path /Users/eaplatanios/Development/GitHub/swift-apis/.build/x86_64-apple-macosx/debug/ModuleCache -swift-version 4.2 -Onone -D SWIFT_PACKAGE -D DEBUG -color-diagnostics -enable-anonymous-context-mangled-names -parse-as-library -module-name TensorFlow -o /Users/eaplatanios/Development/GitHub/swift-apis/.build/x86_64-apple-macosx/debug/TensorFlow.build/Operators/Math.swift.o -o /Users/eaplatanios/Development/GitHub/swift-apis/.build/x86_64-apple-macosx/debug/TensorFlow.build/Operators/NN.swift.o -o /Users/eaplatanios/Development/GitHub/swift-apis/.build/x86_64-apple-macosx/debug/TensorFlow.build/Optimizer.swift.o -index-store-path /Users/eaplatanios/Development/GitHub/swift-apis/.build/x86_64-apple-macosx/debug/index/store -index-system-modules 
1.      Swift version 5.1-dev (LLVM 082dec2e22, Swift 5a6c347496)
2.      While running pass #1956 SILModuleTransform "Differentiation".
0  swift                    0x000000010f22fd35 llvm::sys::PrintStackTrace(llvm::raw_ostream&) + 37
1  swift                    0x000000010f22eff5 llvm::sys::RunSignalHandlers() + 85
2  swift                    0x000000010f230318 SignalHandler(int) + 264
3  libsystem_platform.dylib 0x00007fff759bcb5d _sigtramp + 29
4  libsystem_platform.dylib 0x0000000118064938 _sigtramp + 2724888056
5  libsystem_c.dylib        0x00007fff758766a6 abort + 127
6  libsystem_c.dylib        0x00007fff7583f20d basename_r + 0
7  swift                    0x000000010bcd9690 (anonymous namespace)::ADContext::getOrCreateSubsetParametersThunkForAssociatedFunction(swift::SILValue, swift::SILValue, swift::AutoDiffAssociatedFunctionKind, swift::SILAutoDiffIndices, swift::SILAutoDiffIndices) + 14160
8  swift                    0x000000010bcd517a (anonymous namespace)::ADContext::promoteToDifferentiableFunction(swift::AutoDiffFunctionInst*, swift::SILBuilder&, swift::SILLocation, (anonymous namespace)::DifferentiationInvoker) + 12122
9  swift                    0x000000010bc95038 (anonymous namespace)::ADContext::processAutoDiffFunctionInst(swift::AutoDiffFunctionInst*) + 184
10 swift                    0x000000010bc92371 (anonymous namespace)::Differentiation::run() + 2209
11 swift                    0x000000010bd0e18e swift::SILPassManager::runModulePass(unsigned int) + 734
12 swift                    0x000000010bd0ec64 swift::SILPassManager::execute() + 692
13 swift                    0x000000010b8645eb swift::SILPassManager::executePassPipelinePlan(swift::SILPassPipelinePlan const&) + 187
14 swift                    0x000000010bd14324 swift::runSILDiagnosticPasses(swift::SILModule&) + 132
15 swift                    0x000000010b92c29e swift::CompilerInstance::performSILProcessing(swift::SILModule*, swift::UnifiedStatsReporter*) + 62
16 swift                    0x000000010b6f10e9 performCompile(swift::CompilerInstance&, swift::CompilerInvocation&, llvm::ArrayRef<char const*>, int&, swift::FrontendObserver*, swift::UnifiedStatsReporter*) + 11273
17 swift                    0x000000010b6ed471 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 3025
18 swift                    0x000000010b6934a9 main + 729
19 libdyld.dylib            0x00007fff757d13d5 start + 1

This appears when I make the following function differentiable:

@inlinable
@differentiable
public func log1mexp<T: TensorFlowFloatingPoint>(_ x: Tensor<T>) -> Tensor<T> {
    let isTooSmall = withoutDerivative(at: -x .< T(log(2.0)))
    // This `replacing` will ultimately be a no-op because we will not select this code-path 
    // whenever we use the surrogate `-Tensor(onesLike: x)`.
    let xSafe = x.replacing(with: -Tensor(onesLike: x), where: isTooSmall)
    return log1p(-exp(xSafe)).replacing(with: log(-expm1(x)), where: isTooSmall)
}

@rxwei
Copy link
Contributor

rxwei commented May 31, 2019

How is it defined?

@eaplatanios
Copy link
Contributor Author

@rxwei It's just this:

@_semantics("autodiff.nonvarying")
public func withoutDerivative<T>(at x: T) -> T {
    return x
}

I just pushed the changes so you can see them.

@eaplatanios
Copy link
Contributor Author

@rxwei I made a small reproducible example. I cannot make the following function differentiable:

@inlinable
@differentiable
public func example<T: TensorFlowFloatingPoint>(_ x: Tensor<T>) -> Tensor<T> {
    let ones = withoutDerivative(at: Tensor<T>(ones: x.shape))
    return x.replacing(with: ones, where: Tensor<Bool>(true))
}

I get a similar stacktrace as above and I believe that this error does not have to do with withoutDerivative as I also get it with this:

@inlinable
@differentiable
public func example<T: TensorFlowFloatingPoint>(_ x: Tensor<T>) -> Tensor<T> {
    return x.replacing(with: Tensor<T>(ones: x.shape), where: Tensor<Bool>(true))
}

@rxwei
Copy link
Contributor

rxwei commented Jun 23, 2019

Using targetType didn't work.

  // FIXME: The logic for resolving `assocRef` does not reapply function
  // conversions, which is problematic if `assocFn` is a `partial_apply`
  // instruction.
  SILValue assocRef;
  if (auto *assocFnRef =
          peerThroughFunctionConversions<FunctionRefInst>(assocFn)) {
    auto *assoc = assocFnRef->getReferencedFunctionOrNull();
    assocRef = builder.createFunctionRef(loc, assoc);
  } else if (auto *assocMethodInst =
                 peerThroughFunctionConversions<WitnessMethodInst>(assocFn)) {
    assocRef = builder.createWitnessMethod(
        loc, assocMethodInst->getLookupType(),
        assocMethodInst->getConformance(), assocMethodInst->getMember(),
        thunk->mapTypeIntoContext(assocMethodInst->getType()));
  }
  assert(assocRef && "Expected associated function to be resolved");

Confirmed this is related to this FIXME. cc @dan-zheng

@rxwei
Copy link
Contributor

rxwei commented Jun 23, 2019

Disregard my previous response. I think what is going on here is that the subset parameters thunk generation logic is not handling cases where the original JVP/JVP is already producing a subset-parameters linear map. A proper fix would be to pass in a index subset with respect to the linear map getOrCreateSubsetParametersThunkForAssociatedFunction, not one with respect to the original function.

@eaplatanios
Copy link
Contributor Author

I see. Could you please explain a bit more detail what the index subsets represent and what the linear map is exactly? That will help me a lot in understanding what’s going on and attempting a fix.

@rxwei
Copy link
Contributor

rxwei commented Jun 24, 2019

actualIndices and desiredIndices are with respect to the original function. However, the differential parameters and pullback results may already be w.r.t. a subset, for example:

  • Original: (T0, T1, T2) -> R
  • Actual indices: 0, 2
  • Original differential: (T0, T2) -> R
  • Original pullback: R -> (T0, T2)
  • Desired indices w.r.t. original: 2
  • Desired indices w.r.t. linear map: 1

I have a PR that will fix this.

@rxwei
Copy link
Contributor

rxwei commented Jun 24, 2019

Fixed in swiftlang/swift#25699.

@eaplatanios
Copy link
Contributor Author

Richard thanks a lot for debugging this and helping me also understand what's going on.

rxwei added a commit to swiftlang/swift that referenced this pull request Jun 24, 2019
…25699)

The subset parameters thunk generation logic is not handling cases where the original JVP/JVP is already producing a subset-parameters linear map. This patch fixes it by computing indices w.r.t. the linear map from indices w.r.t. the original function. 

Resolves [TF-594](https://bugs.swift.org/browse/TF-594) and unblocks tensorflow/swift-apis#147.
@eaplatanios
Copy link
Contributor Author

It looks like kokoro does not re-run tests even though I added the kokoro:run label, probably because it has ran them earlier for the same commit. Is there an easy way to force re-run with the new toolchain?

@eaplatanios
Copy link
Contributor Author

Nvm, it just started running them now.

@eaplatanios
Copy link
Contributor Author

@rxwei the CI seems to still be using a toolchain before the auto-diff fix. Could you please re-run tests once the CI toolchain is updated?

@rxwei
Copy link
Contributor

rxwei commented Jun 24, 2019

@bgogul, how long does a new toolchain take to get to Kokoro? A new one was built last night so I assumed that it had propagated to CI.

@eaplatanios
Copy link
Contributor Author

Sorry I believe the toolchain was updated after all but this PR was not. I will merge with master and re-run tests.

@eaplatanios eaplatanios merged commit ef3af7a into tensorflow:master Jun 24, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants