Skip to content

[Autodiff] Assertion failure in certain cases when naming the project _Differentiation. #67727

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
fibrechannelscsi opened this issue Aug 3, 2023 · 2 comments
Labels
AutoDiff bug A deviation from expected or documented behavior. Also: expected but undesirable behavior.

Comments

@fibrechannelscsi
Copy link
Contributor

Description
Preface: The entire purpose of naming the package _Differentiation is to enable Autodiff functionality on toolchains and/or platforms that don't include said functionality.

Steps to reproduce
Here are command-line instructions for reproducing this issue.

  1. Create a directory called _Differentiation.
    mkdir _Differentiation
    cd _Differentiation

  2. Create a new Swift package.
    swift package init --type executable

  3. Copy and paste the code below into the contents of _Differentiation/Sources/_Differentiation/main.swift.

import Swift
extension Dictionary: Differentiable where Value: Differentiable {
    public typealias TangentVector = [Key: Value.TangentVector]
    public mutating func move(by r: TangentVector) {for (c, d) in r {func f() -> Value {preconditionFailure("")}; self[c, default: f()].move(by: d)}}
}
extension Dictionary: AdditiveArithmetic where Value: AdditiveArithmetic {
    public static func + (_ lhs: Self, _ rhs: Self) -> Self { [:] }
    public static func - (_ lhs: Self, _ rhs: Self) -> Self { [:] }
    public static var zero: Self { [:] }
}
func g(n: [String: Double?], at key: String) -> Double? {return nil}
@differentiable(reverse) func d(e: [String: Double?]) -> Double {return 1.0 * g(n: e, at: "s")!}
extension Double: Differentiable {public typealias TangentVector = Double; public mutating func move(by o: TangentVector) {self += o}}
public protocol Differentiable {
    associatedtype TangentVector: Differentiable & AdditiveArithmetic where TangentVector.TangentVector == TangentVector
    mutating func move(by o: TangentVector)
}
public extension Differentiable where TangentVector == Self {@_alwaysEmitIntoClient mutating func move(by o: TangentVector) {self += o}}
extension Optional: Differentiable where Wrapped: Differentiable {
    public struct TangentVector: Differentiable, AdditiveArithmetic {
        public typealias TangentVector = Self
        public var value: Wrapped.TangentVector?
        public init(_ value: Wrapped.TangentVector?) {self.value = value}
        public static var zero: Self {return Self(.zero)}
        public static func + (lhs: Self, rhs: Self) -> Self {return lhs}
        public static func - (lhs: Self, rhs: Self) -> Self {return lhs}
    }
    public mutating func move(by o: TangentVector) {if let v = o.value {self?.move(by: v)}}
}

The assertion failing is given as:
Assertion failed: (getTangentValueCategory(originalValue) == SILValueCategory::Address && rhsAddress->getType().isAddress()), function addToAdjointBuffer, file PullbackCloner.cpp, line 616.

Expected behavior
The compiler should not crash with an internal assertion failure, rather, it ought to provide an appropriate error message.
For example, when the above code is inserted into a project that is not named _Differentiation, it might generate the following error message:
/Users/user/A/Sources/A/main.swift:12:2: error: @differentiable attribute used without importing module '_Differentiation'

Another possible error message with respect to the above code is to indicate that the multiplication operator in line 12 is not differentiable. That is, the error message would say Expression is not differentiable with the multiplication operator in line 12 highlighted as the cause of the error.

Environment

  • Swift compiler version info: Toolchain 2023-07-23 exhibits this issue. The default Xcode 14.2 toolchain simply indicates that the multiplication operator in line 12 is not differentiable.
  • Xcode version info: 14.2.
  • Deployment target: M1

Additional context
Stack trace:

1.	Apple Swift version 5.9-dev (LLVM 9b562f55c38e378, Swift b4ee68bd37c4f7d)
2.	Compiling with the current language version
3.	While evaluating request ExecuteSILPipelineRequest(Run pipelines { Mandatory Diagnostic Passes + Enabling Optimization Passes } on SIL for _Differentiation)
4.	While running pass #328 SILModuleTransform "Differentiation".
5.	While processing // differentiability witness for d(e:)
sil_differentiability_witness [serialized] [reverse] [parameters 0] [results 0] @$s16_Differentiation1d1eSdSDySSSdSgG_tF : $@convention(thin) (@guaranteed Dictionary<String, Optional<Double>>) -> Double {
}

 on SIL function "@$s16_Differentiation1d1eSdSDySSSdSgG_tF".
 for 'd(e:)' (at /Users/user/a/Sources/_Differentiation/New.swift:12:26)
6.	While generating VJP for SIL function "@$s16_Differentiation1d1eSdSDySSSdSgG_tF".
 for 'd(e:)' (at /Users/user/a/Sources/_Differentiation/New.swift:12:26)
7.	While generating pullback for SIL function "@$s16_Differentiation1d1eSdSDySSSdSgG_tF".
 for 'd(e:)' (at /Users/user/a/Sources/_Differentiation/New.swift:12:26)
Stack dump without symbol names (ensure you have llvm-symbolizer in your PATH or set the environment var `LLVM_SYMBOLIZER_PATH` to point to it):
0  swift-frontend           0x00000001074b70bc llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) + 56
1  swift-frontend           0x00000001074b6460 llvm::sys::RunSignalHandlers() + 112
2  swift-frontend           0x00000001074b76fc SignalHandler(int) + 304
3  libsystem_platform.dylib 0x0000000183166a24 _sigtramp + 56
4  libsystem_pthread.dylib  0x0000000183137c28 pthread_kill + 288
5  libsystem_c.dylib        0x0000000183045ae8 abort + 180
6  libsystem_c.dylib        0x0000000183044e44 err + 0
7  swift-frontend           0x000000010760a488 swift::autodiff::PullbackCloner::Implementation::buildPullbackSuccessor(swift::SILBasicBlock*, swift::SILBasicBlock*, llvm::SmallDenseMap<swift::SILValue, llvm::SmallPtrSet<swift::SILBasicBlock*, 4u>, 4u, llvm::DenseMapInfo<swift::SILValue, void>, llvm::detail::DenseMapPair<swift::SILValue, llvm::SmallPtrSet<swift::SILBasicBlock*, 4u>>>&) (.cold.1) + 0
8  swift-frontend           0x0000000102db2148 swift::autodiff::PullbackCloner::Implementation::addToAdjointBuffer(swift::SILBasicBlock*, swift::SILValue, swift::SILValue, swift::SILLocation) + 652
9  swift-frontend           0x0000000102db1d4c swift::autodiff::PullbackCloner::Implementation::accumulateAdjointForOptional(swift::SILBasicBlock*, swift::SILValue, swift::SILValue) + 2080
10 swift-frontend           0x0000000102db0c84 swift::autodiff::PullbackCloner::Implementation::visitSILBasicBlock(swift::SILBasicBlock*) + 3540
11 swift-frontend           0x0000000102dad0f0 swift::autodiff::PullbackCloner::Implementation::run() + 5260
12 swift-frontend           0x0000000102dabc2c swift::autodiff::PullbackCloner::run() + 24
13 swift-frontend           0x0000000102dc8cc0 swift::autodiff::VJPCloner::Implementation::run() + 1368
14 swift-frontend           0x0000000102dc9388 swift::autodiff::VJPCloner::run() + 24
15 swift-frontend           0x0000000102f01248 (anonymous namespace)::DifferentiationTransformer::canonicalizeDifferentiabilityWitness(swift::SILDifferentiabilityWitness*, swift::autodiff::DifferentiationInvoker, swift::IsSerialized_t) + 6212
16 swift-frontend           0x0000000102eff0c4 (anonymous namespace)::Differentiation::run() + 1032
17 swift-frontend           0x0000000102f9fa5c swift::SILPassManager::runModulePass(unsigned int) + 980
18 swift-frontend           0x0000000102fa59e8 swift::SILPassManager::execute() + 624
19 swift-frontend           0x0000000102f9c9e0 swift::SILPassManager::executePassPipelinePlan(swift::SILPassPipelinePlan const&) + 68
20 swift-frontend           0x0000000102f9c964 swift::ExecuteSILPipelineRequest::evaluate(swift::Evaluator&, swift::SILPipelineExecutionDescriptor) const + 68
21 swift-frontend           0x0000000102fdbe18 swift::SimpleRequest<swift::ExecuteSILPipelineRequest, std::__1::tuple<> (swift::SILPipelineExecutionDescriptor), (swift::RequestFlags)1>::evaluateRequest(swift::ExecuteSILPipelineRequest const&, swift::Evaluator&) + 28
22 swift-frontend           0x0000000102fc5210 llvm::Expected<swift::ExecuteSILPipelineRequest::OutputType> swift::Evaluator::getResultUncached<swift::ExecuteSILPipelineRequest>(swift::ExecuteSILPipelineRequest const&) + 252
23 swift-frontend           0x0000000102f9cbd4 swift::executePassPipelinePlan(swift::SILModule*, swift::SILPassPipelinePlan const&, bool, swift::irgen::IRGenModule*) + 84
24 swift-frontend           0x0000000102fc72b4 swift::runSILDiagnosticPasses(swift::SILModule&) + 192
25 swift-frontend           0x00000001028aa6cc swift::CompilerInstance::performSILProcessing(swift::SILModule*) + 68
26 swift-frontend           0x00000001026da358 performCompileStepsPostSILGen(swift::CompilerInstance&, std::__1::unique_ptr<swift::SILModule, std::__1::default_delete<swift::SILModule>>, llvm::PointerUnion<swift::ModuleDecl*, swift::SourceFile*>, swift::PrimarySpecificPaths const&, int&, swift::FrontendObserver*) + 792
27 swift-frontend           0x00000001026d9a4c swift::performCompileStepsPostSema(swift::CompilerInstance&, int&, swift::FrontendObserver*) + 600
28 swift-frontend           0x00000001026e8dfc withSemanticAnalysis(swift::CompilerInstance&, swift::FrontendObserver*, llvm::function_ref<bool (swift::CompilerInstance&)>, bool) + 160
29 swift-frontend           0x00000001026dc5d0 performCompile(swift::CompilerInstance&, int&, swift::FrontendObserver*) + 740
30 swift-frontend           0x00000001026db530 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 2504
31 swift-frontend           0x0000000102522760 swift::mainEntry(int, char const**) + 2144
32 dyld                     0x0000000182ddff28 start + 2236

Given the above stack trace, we can see that the project itself is called a, whereas the term _Differentiation simply appears in a directory name under Sources. It might be the case that all that needs to happen is to have _Differentiation appear in the symbol name of a function.

@fibrechannelscsi fibrechannelscsi added bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. triage needed This issue needs more specific labels labels Aug 3, 2023
@asl
Copy link
Contributor

asl commented Aug 9, 2023

Likely dup of #59876?

@fibrechannelscsi
Copy link
Contributor Author

It looks like the things that cause the issue are similar (overriding _Differentiation in some manner), but the stack trace in this issue looks different from the ones in 59876.

@hborla hborla added AutoDiff and removed triage needed This issue needs more specific labels labels Apr 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
AutoDiff bug A deviation from expected or documented behavior. Also: expected but undesirable behavior.
Projects
None yet
Development

No branches or pull requests

3 participants