如何从自动微分中获得更多性能?
How to get more performance out of automatic differentiation?
我很难优化一个大部分工作都依赖 ad
s conjugateGradientDescent
函数的程序。
基本上我的代码是对用 Matlab 和 C 编写的 old papers code 的翻译。我没有对其进行测量,但该代码是 运行ning 每秒迭代几次。我的是每次迭代的分钟数......
此存储库中提供了代码:
有问题的代码可以通过以下命令 运行:
$ cd aer-utils
$ cabal sandbox init
$ cabal sandbox add-source ../aer
$ cabal run learngabors
使用 GHC 分析工具,我已经确认下降实际上是花费大部分时间的部分:
(互动版在这里:https://dl.dropboxusercontent.com/u/2359191/learngabors.svg)
-s
告诉我生产力很低:
Productivity 33.6% of total user, 33.6% of total elapsed
根据我收集到的信息,有两件事可能会带来更高的性能:
拆箱: 目前我使用自定义矩阵实现(在 src/Data/SimpleMat.hs
中)。这是我可以让 ad
使用矩阵的唯一方法(参见:How to do automatic differentiation on hmatrix?). My guess is that by using a matrix type like newtype Mat w h a = Mat (Unboxed.Vector a)
would achieve better performance due to unboxing and fusion. I found some code 有 ad
个未装箱向量的实例,但到目前为止我还不能使用这些与 conjugateGradientFunction
.
矩阵导数: 在一封电子邮件中,我现在找不到爱德华提到最好使用 Forward
个实例对于矩阵类型,而不是让矩阵填充 Forward
个实例。我有一个模糊的想法如何实现它,但还没有弄清楚我将如何根据 ad
s 类型 类.
来实现它
这个问题可能太宽泛,无法在 SO 上回答,所以如果您愿意帮助我,请随时通过 Github.
与我联系
你 运行 进入了当前 ad
库的最坏情况。
FWIW- 您将无法将现有的 ad
classes/types 与 "matrix/vector ad" 一起使用。这将是一项相当大的工程工作,请参阅 https://github.com/ekmett/ad/issues/2
至于为什么不能拆箱:conjugateGradient
需要能够在您的函数上使用 Kahn
模式或两级转发模式。前者阻止它使用未装箱的向量,因为数据类型带有语法树,并且不能被拆箱。由于各种技术原因,我还没有弄清楚如何使它像标准 Reverse
模式一样使用固定大小的 'tape'。
我认为这里的 "right" 答案是让我们坐下来弄清楚如何正确获得 matrix/vector AD 并将其集成到包中,但我承认我也有点时间片现在就细细地给予它应有的关注。
如果你有机会在 irc.freenode.net 上通过#haskell-lens 摆动,我很乐意谈论这个 space 中的设计并提供建议。 Alex Lang 也一直致力于 ad
,并且经常出现在那里并且可能有想法。
我很难优化一个大部分工作都依赖 ad
s conjugateGradientDescent
函数的程序。
基本上我的代码是对用 Matlab 和 C 编写的 old papers code 的翻译。我没有对其进行测量,但该代码是 运行ning 每秒迭代几次。我的是每次迭代的分钟数......
此存储库中提供了代码:
有问题的代码可以通过以下命令 运行:
$ cd aer-utils
$ cabal sandbox init
$ cabal sandbox add-source ../aer
$ cabal run learngabors
使用 GHC 分析工具,我已经确认下降实际上是花费大部分时间的部分:
(互动版在这里:https://dl.dropboxusercontent.com/u/2359191/learngabors.svg)
-s
告诉我生产力很低:
Productivity 33.6% of total user, 33.6% of total elapsed
根据我收集到的信息,有两件事可能会带来更高的性能:
拆箱: 目前我使用自定义矩阵实现(在
src/Data/SimpleMat.hs
中)。这是我可以让ad
使用矩阵的唯一方法(参见:How to do automatic differentiation on hmatrix?). My guess is that by using a matrix type likenewtype Mat w h a = Mat (Unboxed.Vector a)
would achieve better performance due to unboxing and fusion. I found some code 有ad
个未装箱向量的实例,但到目前为止我还不能使用这些与conjugateGradientFunction
.矩阵导数: 在一封电子邮件中,我现在找不到爱德华提到最好使用
Forward
个实例对于矩阵类型,而不是让矩阵填充Forward
个实例。我有一个模糊的想法如何实现它,但还没有弄清楚我将如何根据ad
s 类型 类. 来实现它
这个问题可能太宽泛,无法在 SO 上回答,所以如果您愿意帮助我,请随时通过 Github.
与我联系你 运行 进入了当前 ad
库的最坏情况。
FWIW- 您将无法将现有的 ad
classes/types 与 "matrix/vector ad" 一起使用。这将是一项相当大的工程工作,请参阅 https://github.com/ekmett/ad/issues/2
至于为什么不能拆箱:conjugateGradient
需要能够在您的函数上使用 Kahn
模式或两级转发模式。前者阻止它使用未装箱的向量,因为数据类型带有语法树,并且不能被拆箱。由于各种技术原因,我还没有弄清楚如何使它像标准 Reverse
模式一样使用固定大小的 'tape'。
我认为这里的 "right" 答案是让我们坐下来弄清楚如何正确获得 matrix/vector AD 并将其集成到包中,但我承认我也有点时间片现在就细细地给予它应有的关注。
如果你有机会在 irc.freenode.net 上通过#haskell-lens 摆动,我很乐意谈论这个 space 中的设计并提供建议。 Alex Lang 也一直致力于 ad
,并且经常出现在那里并且可能有想法。