朱莉娅:如何查看去矢量化的代码?

时间:2018-08-14 21:23:11

标签: julia

我想看一些here

表达式的去矢量化代码
obj.mask = exp.(1.0im*lambda*obj.dt/2.);

如何在Julia中以去矢量化形式打印通用表达式?

1 个答案:

答案 0 :(得分:2)

我不认为您要的东西存在(如果我弄错了,请证明我错了!)

您能做的最好的就是使用@code_lowered, @code_typed, @code_llvm, @code_native宏(尤其是@code_lowered)来查看Julia代码段发生了什么。但是,由于Julia 不会在内部将所有点都转换为显式的for循环,因此这些片段中的任何一个都不会为您显示代码的for循环版本。

示例:

julia> a,b = rand(3), rand(3);

julia> f(a,b) = a.*b
f (generic function with 1 method)

julia> @code_lowered f(a,b)
CodeInfo(
1 1 ─ %1 = Base.Broadcast.materialize                                                                                           │
  │   %2 = Base.Broadcast.broadcasted                                                                                           │
  │   %3 = (%2)(Main.:*, a, b)                                                                                                  │
  │   %4 = (%1)(%3)                                                                                                             │
  └──      return %4                                                                                                            │
)

因此,朱莉娅将.*转换为Base.Broadcast.broadcasted调用。当然,我们可以走得更远

julia> @which Base.Broadcast.broadcasted(Main.:*, a, b)
broadcasted(f, arg1, arg2, args...) in Base.Broadcast at broadcast.jl:1139

并在第1139行中检查broadcast.jl,以此类推,以追踪将要调用的实际broadcasted方法(也许Tim Holy的Rebugger在这里很有用:D)。但是正如我之前所说,其中不会有for循环。相反,您会发现以下内容:

broadcasted(::DefaultArrayStyle{1}, ::typeof(*), r::AbstractRange, x::Number) = range(first(r)*x, step=step(r)*x, length=length(r))
broadcasted(::DefaultArrayStyle{1}, ::typeof(*), r::StepRangeLen{T}, x::Number) where {T} =
    StepRangeLen{typeof(T(r.ref)*x)}(r.ref*x, r.step*x, length(r), r.offset)
broadcasted(::DefaultArrayStyle{1}, ::typeof(*), r::LinRange, x::Number) = LinRange(r.start * x, r.stop * x, r.len)

更新

好吧,最终,我在copyto!的{​​{1}}中找到了for循环。但这可能是深入兔子洞的地方。