Swift中定义标量入参向量输出可微函数的正确方式?
Swift自动微分(AD)使用问题
我是Swift初学者,正在测试其自动微分(AD)功能,编写了如下标量转向量的可微分函数:
import Foundation import _Differentiation @differentiable(reverse) func numToVec1(_ x: Float) -> Array<Float>.DifferentiableView { typealias V = Array<Float> return V.DifferentiableView([sin(x), cos(x), x*x]) }
尝试用derivative(at:of:)计算导数:
let scalarInput: Float = 42.0 let dnv1 = derivative(at: scalarInput, of: numToVec1)
运行时错误
代码可编译,但运行时报错:
_Differentiation/DifferentiationUtilities.swift:40: Fatal error: JVP does not exist. Use '-Xfrontend -enable-experimental-forward-mode-differentiation' to enable differential-first differentiation APIs. Current stack trace: 0 libswiftCore.so 0x00007f4107c1aa60 _swift_stdlib_reportFatalErrorInFile + 112 1 libswiftCore.so 0x00007f410790d3af <unavailable> + 1442735 2 libswiftCore.so 0x00007f410790d1c7 <unavailable> + 1442247 3 libswiftCore.so 0x00007f410790bfd0 _assertionFailure(_:_:file:line:flags:) + 364 4 libswift_Differentiation.so 0x00007f410805d464 <unavailable> + 169060 5 output.s 0x000055abacce9189 <unavailable> + 8585 6 output.s 0x000055abacce8e37 <unavailable> + 7735 7 libswift_Differentiation.so 0x00007f410805b820 valueWithDifferential<A, B>(at:of:) + 106 8 libswift_Differentiation.so 0x00007f410805bca0 differential<A, B>(at:of:) + 93 9 libswift_Differentiation.so 0x00007f410805c050 derivative<A, B>(at:of:) + 89 10 output.s 0x000055abacce8c09 <unavailable> + 7177 11 libc.so.6 0x00007f410759df90 __libc_start_main + 243 12 output.s 0x000055abacce87fe <unavailable> + 6142 Program terminated with signal: SIGILL
添加编译标志后的编译错误
按照提示添加-Xfrontend -enable-experimental-forward-mode-differentiation编译标志后,出现编译时断言错误:
Assertion failed: it != bufferMap.end() && "Tangent buffer should already exist", file D:\a\1\s\swift\lib\SILOptimizer\Differentiation\JVPCloner.cpp, line 317 Please submit a bug report (https://swift.org/contributing/#reporting-bugs) and include the crash backtrace. Stack dump: ...
写法规范确认
你的写法逻辑上存在API模式不匹配的问题,但核心逻辑符合Swift自动微分规范:
API模式不匹配:
你标记了函数为@differentiable(reverse)(反向模式),但derivative(at:of:)是**正向模式(JVP)**的API。反向模式应使用梯度相关API,比如valueWithGradient(at:of:):let scalarInput: Float = 42.0 let (outputVec, inputGrad) = valueWithGradient(at: scalarInput, of: numToVec1) // inputGrad 即为输入x的梯度,对应 [cos(42), -sin(42), 84]正向模式的问题:
如果要使用正向模式计算导数,需要将函数标记为@differentiable(reverse, forward)或@differentiable(forward),同时启用正向模式编译标志。但你遇到的编译器断言错误是Swift编译器在处理数组DifferentiableView正向模式时的实现bug,并非代码写法错误。
综上,你的代码写法本身符合规范,运行时错误是API模式不匹配导致,而编译断言错误属于编译器自身bug,确实需要提交bug报告。
内容的提问来源于stack exchange,提问作者loonatick
相关产品推荐
相关产品推荐

